package com.airticketbooking.service.serviceImpl;


import com.airticketbooking.common.constant.StatusConstant;
import com.airticketbooking.common.utils.BeanUtils;
import com.airticketbooking.dto.TicketDTO;
import com.airticketbooking.mapper.FlightScheduleMapper;
import com.airticketbooking.po.*;
import com.airticketbooking.query.TicketPageQuery;
import com.airticketbooking.vo.SeatVO;
import com.airticketbooking.vo.TicketVO;
import com.airticketbooking.mapper.TicketMapper;
import com.airticketbooking.service.*;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * (Ticket)表服务实现类
 *
 * @author makejava
 * @since 2024-10-21 16:21:18
 */
@Service("ticketService")
@RequiredArgsConstructor
public class TicketServiceImpl implements TicketService {

	private final TicketMapper ticketMapper;

	private final SeatService seatService;


	private final FlightService flightService;

	private final FlightScheduleMapper flightScheduleMapper;

	private final SeatClassService seatClassService;

	@Override
	public Page<TicketVO> pageQuerylist(TicketPageQuery ticketPageQuery) {

		PageHelper.startPage(ticketPageQuery.getPageNo(), ticketPageQuery.getPageSize());

		Page<Ticket> TicketsPage = ticketMapper.pageQuerylist(ticketPageQuery);


//	得出对应seat_id的座位信息

		List<TicketVO> ticketVOs = new ArrayList<>();

		for (Ticket ticket : TicketsPage.getResult()) {

			TicketVO ticketVO = new TicketVO();
//			复制ticket属性到ticketVO中
			BeanUtils.copyProperties(ticket, ticketVO);
//得到seat_id对应的座位信息
			SeatVO seat = seatService.getById(ticket.getSeatId());

//			得到seat_class_id对应的座位类型信息
			Seatclass seatClass = seatClassService.getSeatClassById(seat.getClassId());


//得到座位属性复制到ticketVO中
			BeanUtils.copyProperties(seat, ticketVO);
			BeanUtils.copyProperties(seatClass, ticketVO);

//得到schedule_id对应的航班信息
			FlightSchedule schedule = flightScheduleMapper.getById(ticket.getScheduleId());
			BeanUtils.copyProperties(schedule, ticketVO);

//得到flight_id对应的航班信息
			Flight flight = flightService.getFlightById(schedule.getFlightId());

			if (flight.getStatus() == 1) {
				BeanUtils.copyProperties(flight, ticketVO);
			}

			ticketVOs.add(ticketVO);
		}

//		将ticketVOs转换为Page<TicketVO>
		Page<TicketVO> ticketVOPage = new Page<>();
		ticketVOPage.setTotal(TicketsPage.getTotal());
		for (TicketVO ticketVO : ticketVOs) {
			ticketVOPage.add(ticketVO);
		}

		return ticketVOPage;


	}

	@Override
	@Transactional
	public void addTickets(Integer scheduleId) {


//		得到schedule_id对应的班次安排
		FlightSchedule schedule = flightScheduleMapper.getById(scheduleId);

		if (schedule.getStatus() != StatusConstant.SCHEDULE_AVAILABLE) {

			throw new RuntimeException("该班次不可生成票据");

		}


//	    得到flight_id对应的航班信息
		Integer airplaneId = flightService.getAirplaneIdById(schedule.getFlightId());

//		得到flight_id对应的seats信息
		Flight flight = flightService.getFlightById(schedule.getFlightId());
		Integer flightDistance = flight.getFlightDistance();


//			 得到airplaneid对应的seats信息
		List<Seat> seats = seatService.getSeatsByAirplaneId(airplaneId);


		if (seats.size() == 0) {
			throw new RuntimeException("该航班无可设置票的座位");
		}

		for (Seat seat : seats) {

			if (seat.getStatus() != StatusConstant.ENABLE) {
				throw new RuntimeException("该座位不可设为票据");
			}


			Ticket ticket = new Ticket();

//			计算票价
			BigDecimal price = calculatePrice(flightDistance, seat.getClassId());

			ticket.setScheduleId(schedule.getScheduleId());
			ticket.setAirplaneId(airplaneId);
			ticket.setPrice(price);
			ticket.setSeatId(seat.getSeatId());
			ticket.setCreateTime(LocalDateTime.now());
			ticket.setUpdateTime(LocalDateTime.now());
			ticketMapper.add(ticket);

			//			更新seat状态
			seat.setStatus(StatusConstant.DISABLE);
			seatService.updateSeat(seat);

		}


	}

	@Override
	public void update(TicketDTO ticketDTO) {


		ticketDTO.setUpdateTime(LocalDateTime.now());

		Ticket ticket = new Ticket();
		BeanUtils.copyProperties(ticketDTO, ticket);

		ticketMapper.update(ticket);
	}

	@Override
	public TicketVO getTicketById(Integer id) {


		Ticket ticket = ticketMapper.getTicketById(id);

//	得出对应seat_id的座位信息


		TicketVO ticketVO = new TicketVO();
//			复制ticket属性到ticketVO中
		BeanUtils.copyProperties(ticket, ticketVO);
//得到seat_id对应的座位信息
		SeatVO seat = seatService.getById(ticket.getSeatId());

//			得到seat_class_id对应的座位类型信息
		Seatclass seatClass = seatClassService.getSeatClassById(seat.getClassId());


//得到座位属性复制到ticketVO中
		BeanUtils.copyProperties(seat, ticketVO);
		BeanUtils.copyProperties(seatClass, ticketVO);

//得到schedule_id对应的班次信息
		FlightSchedule schedule = flightScheduleMapper.getById(ticket.getScheduleId());
		BeanUtils.copyProperties(schedule, ticketVO);

//得到flight_id对应的航班信息
		Flight flight = flightService.getFlightById(schedule.getFlightId());

		BeanUtils.copyProperties(flight, ticketVO);

		ticketVO.setStatus(ticket.getStatus());

		return ticketVO;
	}

	@Override
	@Transactional
	public Integer startOrstopTicket(Integer scheduleId) {

		if (scheduleId == null) {
			throw new RuntimeException("scheduleId不能为空");
		}

		Integer newStatus = StatusConstant.DISABLE;

		List<Ticket> ticketByScheduleId = ticketMapper.getTicketByScheduleId(scheduleId);


		for (Ticket ticket1 : ticketByScheduleId) {
			if (ticket1.getStatus() == StatusConstant.TICKET_COULD_BOOK) {

				ticketMapper.startOrstopTicket(scheduleId, StatusConstant.DISABLE);
				newStatus = StatusConstant.TICKET_COULD_BOOK;
			} else if (ticket1.getStatus() == StatusConstant.DISABLE) {

				ticketMapper.startOrstopTicket(scheduleId, StatusConstant.TICKET_COULD_BOOK);
			}
		}


		return newStatus;
	}

//

	public static BigDecimal calculatePrice(Integer flightDistance, Integer classId) {
		BigDecimal distance = BigDecimal.valueOf(flightDistance);
		BigDecimal rate1 = BigDecimal.valueOf(0.8);
		BigDecimal rate2 = BigDecimal.valueOf(0.7);
		BigDecimal rate3 = BigDecimal.valueOf(0.6);

		if (classId == 1) {
			return distance.multiply(rate1);
		} else if (classId == 2) {
			return distance.multiply(rate2);
		} else if (classId == 3) {
			return distance.multiply(rate3);
		}

		return null;
	}


}


